package ks.server.controllers.commands.admin.user;

import java.util.Collection;
import java.util.Vector;

import ks.framework.common.Message;
import ks.framework.communicator.Communicator;
import ks.framework.interfaces.IProcessMessage;
import ks.server.controllers.commands.general.user.UserConnectedController;
import ks.server.controllers.requests.AckRequest;
import ks.server.controllers.requests.NackRequest;
import ks.server.ipc.Listener;
import ks.server.persist.PersistentUserManager;
import ks.server.ServerContext;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * Process request to kick users.
 * 
 * @author Christopher Page
 */
public class UserKickController implements IProcessMessage {

	/** Primary agent to whom we can communicate our messages. */
	Communicator com;
	
	public UserKickController (Communicator com) {
		this.com = com;
	}
	
	/**
	 * Process the message
	 * 
	 * @param m The message to process.
	 * @return A boolean value.
	 */
	public boolean process(Message m) {
		PersistentUserManager um = ServerContext.getUserManager();
		
		// Verify that command originator is an admin
		if (um.getUser(m.getOriginator()) == null) {
			Listener.nack(m, 4, "Unable to delete users: what!? I don't even...");
			return true;
		}
		else if (!um.getUser(m.getOriginator()).isAdmin()) {
			Listener.nack(m, 4, "Unable to delete user: access denied.");
			return true;
		}
		
		Vector<String> usersToKick = new Vector<String>();
		
		NodeList playernameLst = m.contents().getChildNodes();
		Node playernameTmpNode;
		Node playernameNameTmpNode;
		
		// get users to kick
		for (int i = 0; i < playernameLst.getLength(); i++) {
			playernameTmpNode = playernameLst.item(i);
			playernameNameTmpNode = playernameTmpNode.getAttributes().getNamedItem("name");
			
			if (playernameNameTmpNode != null) {
				usersToKick.add(playernameNameTmpNode.getNodeValue());
			}
			else {
				Listener.nack(m, 4, "Badly formatted playername data.");
			}
		}
		
		StringBuilder sb = new StringBuilder("<request version='1.0' id='589a39591271844e3fbe32bbb9281ad9'>");
		
		// get usernames of online users
		Collection<String> onlineUsernames = com.getOnlineUsers();
		
		boolean kickedUser = false;
		
		for (String uN : usersToKick) {
			if (onlineUsernames.contains(uN)) {
				com.disconnectUser(uN);
				sb.append("<kicked player=\"" + uN + "\" />");
				kickedUser = true;
			}
		}
		
		if (kickedUser) {
			new AckRequest(com).send(m, "Kicked at least 1 user.", m.getOriginator());
			Listener.ack(m, "Kicked at least 1 user.");
			sb.append("</request>");
		
			Document d = Message.construct(sb.toString());
			Message r = new Message(d);
			r.setRecipient(m.getOriginator());
			com.distribute(r);
			
			return new UserConnectedController(com).process(m);
		}
		else {
			new NackRequest(com).send(m, 4, "No users kicked.", m.getOriginator());
			return false;
		}
	}
}
